package com.sample.springbatch.job.sample.config;

import com.sample.springbatch.job.config.BaseConfig;
import com.sample.springbatch.job.sample.processor.UserItemProcessor;
import com.sample.springbatch.model.User;
import com.sample.springbatch.job.sample.service.TaskletStepService;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.task.SyncTaskExecutor;

import javax.sql.DataSource;


/**
 * Created by zwg on 2017/7/14.
 */
@Configuration
public class TestJobConfig extends BaseConfig {



    @Autowired
    public DataSource dataSource;


    @Bean
    public FlatFileItemReader<User> reader() {
        FlatFileItemReader<User> reader = new FlatFileItemReader<User>();
        reader.setResource(new ClassPathResource("jobdata/sample-user-data.csv"));
        reader.setLineMapper(new DefaultLineMapper<User>() {{
            setLineTokenizer(new DelimitedLineTokenizer() {{
                setNames(new String[] { "firstName", "lastName" });
            }});
            setFieldSetMapper(new BeanWrapperFieldSetMapper<User>() {{
                setTargetType(User.class);
            }});
        }});
        return reader;
    }

    @Bean
    public UserItemProcessor processor() {
        return new UserItemProcessor();
    }

    @Bean
    public JdbcBatchItemWriter<User> writer() {
        JdbcBatchItemWriter<User> writer = new JdbcBatchItemWriter<User>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<User>());
        writer.setSql("INSERT INTO user (first_name, last_name) VALUES (:firstName, :lastName)");
        writer.setDataSource(dataSource);
        return writer;
    }

    @Bean(name = "importUserJob")
    public Job importUserJob() {
    //public Job importUserJob(MyJobListener listener) {
        return jobBuilderFactory.get("importUserJob")
                .incrementer(new RunIdIncrementer())
                //.listener(listener)
                .flow(step1())
                .end()
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<User, User> chunk(100)
                .reader(reader())
                .processor(processor())
                .writer(writer())
                .build();
    }

    @Bean(name = "taskLetJob")
    public Job taskLetJob() {
        return jobBuilderFactory.get("taskLetJob")
                .incrementer(new RunIdIncrementer())
                //.listener(listener)
                .flow(taskLetStep())
                .end()
                .build();
    }

    @Bean
    public Step taskLetStep() {
        return stepBuilderFactory.get("taskLetStep")
                .tasklet(tasklet())
                .tasklet(tasklet2())
                .taskExecutor(new SyncTaskExecutor())
                .throttleLimit(5)
                .build();
    }

    @Autowired
    TaskletStepService taskletStepService;

    @Bean
    public Tasklet tasklet(){
        MethodInvokingTaskletAdapter tasklet = new MethodInvokingTaskletAdapter();
        tasklet.setTargetObject(taskletStepService);
        tasklet.setTargetMethod("showMe");
        return tasklet;
    }

    @Bean
    public Tasklet tasklet2(){
        MethodInvokingTaskletAdapter tasklet = new MethodInvokingTaskletAdapter();
        tasklet.setTargetObject(taskletStepService);
        tasklet.setTargetMethod("showMe2");
        return tasklet;
    }
}
